<?php
/**
 * @author		João Batista Neto
 * @brief		Objetos que representam cada tipo do retorno da API
 * @package		dso.buscape.result.type
 */

require_once 'dso/buscape/result/type/BuscapeComposite.php';

/**
 * @brief		Especificação de um produto
 * @class		BuscapeSpecification
 * @ingroup		Types
 */
class BuscapeSpecification extends BuscapeComposite {
	/**
	 * @brief	Lista de links
	 * @var		RecursiveComponentIterator
	 */
	private $links;

	/**
	 * @brief	Adiciona um novo link à especificação.
	 * @param	$link BuscapeLink O link que será adicionado.
	 * @return	BuscapeSpecification Esta especificação
	 */
	public function addLink( BuscapeLink $link ){
		if ( is_null( $this->links ) ){
			$this->links = new RecursiveComponentIterator();
		}

		$this->links->append( $link );

		return $this;
	}

	/**
	 * @brief	Verifica se um filho é aceitável pelo componente
	 * @param	$child BuscapeComponent
	 * @return	boolean
	 * @see		BuscapeComponent.accept()
	 */
	protected function accept( IObject $child ){
		if ( parent::accept( $child ) ){
			$reflection = $child->getClass();

			return $reflection->getName() == 'BuscapeItem' || $reflection->isSubclassOf( 'BuscapeItem' );
		}

		return false;
	}

	/**
	 * @brief	Cria uma instância do objeto com os argumentos passados
	 * @param	$args array Lista de argumentos que serão utilizados para criação do objeto
	 * @return	BuscapeSpecification
	 */
	public static function createInstante( array $args ){
		$specification = new BuscapeSpecification();

		foreach ( $args as $property => $value ){
			$specification->$property = $value;
		}

		return $specification;
	}

	/**
	 * @brief	Recupera um iterator para os links
	 * @return	RecursiveComponentIterator
	 * @throws	BadMethodCallException Se não houverem links
	 */
	public function getLinks(){
		if ( !is_null( $this->links ) ){
			return $this->links->getIterator();
		} else {
			throw new BadMethodCallException( 'Não existem links para serem retornados.' );
		}
	}
}